/*
    同步：同步问题是保证线程安全的情况下，让我们的线程访问资源具有一定的顺序性。 -- 条件变量
    条件变量：1、通知机制  2、队列（让线程等待的队列）
    条件变量必须依赖锁的使用！！
*/

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <vector>

using namespace std;
#define NUM 4

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

int tickets = 5000; 

class threadData
{
public:
    threadData(int number)
    {
        _thread_name = "thread-" + to_string(number);
    }

    string _thread_name;
};

void* getTicket(void* args)
{
    threadData* td = static_cast<threadData*>(args);
    const char* name = td->_thread_name.c_str();
    while(true)
    {
        pthread_mutex_lock(&lock); 

        if(tickets > 0)
        {
            usleep(1000); 
            printf("who=%s, get a ticket: %d\n", name, tickets);
            tickets--;
            pthread_mutex_unlock(&lock);
        }
        else{
            pthread_mutex_unlock(&lock);
            break;
        }
        usleep(15); 
    }
    printf("%s...quit\n", name);
    return nullptr;
}

int main()
{
    // pthread_mutex_t lock;
    // pthread_mutex_init(&lock,nullptr);

    vector<pthread_t> tids;
    vector<threadData*> thread_datas;
    for(int i = 1; i <= NUM; ++i)
    {
        pthread_t tid;
        // threadData* td = new threadData(i, &lock);
        threadData* td = new threadData(i);
        thread_datas.push_back(td);
        pthread_create(&tid, nullptr, getTicket, thread_datas[i-1]);
        tids.push_back(tid);
    }

    for(auto thread : tids)
    {
        pthread_join(thread, nullptr);
    }

    for(auto td : thread_datas)
    {
        delete td;
    }

    // pthread_mutex_destroy(&lock);
    return 0;
}


